package  
{
    import flash.display.Sprite;
    import flash.events.KeyboardEvent;
    import mge.Ease;
    import mge.Timer;
	import mge.ui.Button;
	/**
	 * Provides navigation between buttons with keyboard.
     * 
	 * @author ivan
	 */
	public class ButtonContainer 
	{
		private var autoRepeatTimer:Timer = new Timer(200);
        private var autoRepeating:Boolean = true;
        
		public function ButtonContainer(parent:Sprite) 
		{
			this.parent = parent;
            
            sprite = new Sprite;
            
            parent.addChild(sprite);
            
            parent.parent.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            parent.parent.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
            
            autoRepeatTimer.start();
		}
        
        public function visible(value:Boolean):void
        {
            parent.alpha = value ? 1.0 : 0.5;
        }
        
        public function getButton(name:String):Button
        {
            for (var i:int = 0; i < buttons.length; i++)
            {
                if (buttons[i].name == name)
                    return buttons[i];
            }
            
            return null;
        }
        
        private function onKeyDown(e:KeyboardEvent):void
        {
            if (autoRepeating && !autoRepeatTimer.finished()) return;
            autoRepeatTimer.start();
            autoRepeating = true;
            
            if (e.keyCode == 38) // UP
            {
                selectPrev();
                buttons[selected].onMouseOver(null);
                buttons[selected].onMouseDown(null);
            }
            else if (e.keyCode == 40) // DOWN
            {
                selectNext();
                buttons[selected].onMouseOver(null);
                buttons[selected].onMouseDown(null);
            }
            else if (e.keyCode == 32) // SPACE
            {
                buttons[selected].onMouseOver(null);
                buttons[selected].onMouseDown(null);
            }
        }
        
        private function onKeyUp(e:KeyboardEvent):void
        {
            autoRepeating = false;
            
            if (buttons.length == 0) return;
            if (e.keyCode == 38 ||
                e.keyCode == 40 ||
                e.keyCode == 32) // SPACE
            {
                buttons[selected].onMouseUp(null);
            }
        }
        
        public function selectPrev():void
        {
            if (buttons.length == 0) return;
            var prevSelected:int = selected;
            do
            {
                selected--;
                if (selected < 0) selected = buttons.length-1;
            } while (!selectable(buttons[selected]) && selected != prevSelected)
            
            if (selected == prevSelected) return;
            
            buttons[prevSelected].selected = false;
            buttons[selected].selected = true;
        }
        
        public function selectNext():void
        {
            if (buttons.length == 0) return;
            var prevSelected:int = selected;
            do
            {
                selected++;
                if (selected >= buttons.length) selected = 0;
            } while (!selectable(buttons[selected]) && selected != prevSelected)
            
            if (selected == prevSelected) return;
            
            buttons[prevSelected].selected = false;
            buttons[selected].selected = true;
        }
        
        private function selectable(button:Button):Boolean
        {
            return button.enabled && button.keyboardNavigable;
        }
        
		
		public function addButton(button:Button):void
        {
            selected = 0;
            buttons.push(button);
            button.parent = sprite;
            rearrange();
            button.addOnClickCallback(onClickCallback);
        }
        
        private function onClickCallback(name:String):void
        {
            buttons[selected].selected = false;
            for (var i:int = 0; i < buttons.length; i++)
            {
                if (buttons[i].name == name)
                    selected = i;
            }
            buttons[selected].selected = true;
        }
        
        private function rearrange():void
        {
            if (_rearrangeFunction != null) _rearrangeFunction(buttons);
        }
        
        public function set rearrangeFunction(f:Function):void
        {
            for (var i:int = 0; i < buttons.length; i++)
            {
                buttons[i].scale = 1;
            }    
            _rearrangeFunction = f;
            _rearrangeFunction(buttons);
        }
        private var _rearrangeFunction:Function;
        
        private var parent:Sprite;
        private var buttons:Vector.<Button> = new Vector.<Button>();
        
        public var x:int;
        public var y:int;
        
        private var sprite:Sprite;
        
        private var selected:int;
	}

}